package org.example.config;


import org.example.controller.BaseController;
import org.example.controller.HighStakesController;
import org.example.controller.SessionController;
import org.example.controller.StakeController;
import org.example.service.BettingService;
import org.example.service.SessionService;
import org.example.storage.BettingStorage;
import org.example.storage.SessionStorage;

import java.util.HashMap;
import java.util.Map;

/**
 * 集中式路由和依赖配置
 */
public class RouterConfig {
    // 存储路径模式 -> 控制器类的映射
    private final Map<String, Class<? extends BaseController>> routeMappings = new HashMap<>();

    // 存储依赖实例
    private final Map<Class<?>, Object> dependencies = new HashMap<>();

    // 单例实例
    private static RouterConfig instance;

    public RouterConfig() {
        initializeDependencies();
        initializeMappings();
    }

    /**
     * 获取单例实例
     */
    public static synchronized RouterConfig getInstance() {
        if (instance == null) {
            instance = new RouterConfig();
        }
        return instance;
    }


    /**
     * 初始化所有依赖实例
     * 依赖注入xml扫描注入过于繁琐 暂时不做
     */
    private void initializeDependencies() {
        // 创建并存储所有服务实例
        SessionStorage sessionStorage = new SessionStorage();
        BettingStorage bettingStorage = new BettingStorage();
        dependencies.put(SessionStorage.class, sessionStorage);
        dependencies.put(BettingStorage.class, bettingStorage);

        SessionService sessionService = new SessionService((SessionStorage)dependencies.get(SessionStorage.class));

        BettingService bettingService = new BettingService((SessionStorage)dependencies.get(SessionStorage.class),
                (BettingStorage)dependencies.get(BettingStorage.class));

        dependencies.put(SessionService.class, sessionService);
        dependencies.put(BettingService.class, bettingService);

        // 初始化控制器实例
        SessionController sessionController = new SessionController(sessionService);
        StakeController stakeController = new StakeController(bettingService);
        HighStakesController highStakesController = new HighStakesController(bettingService);

        dependencies.put(SessionController.class, sessionController);
        dependencies.put(StakeController.class, stakeController);
        dependencies.put(HighStakesController.class, highStakesController);

        System.out.println("Dependencies initialized:");
        dependencies.forEach((clazz, instance) ->
                System.out.println("  " + clazz.getSimpleName() + " -> " + instance.getClass().getSimpleName())
        );
    }

    /**
     * 初始化路由映射
     */
    private void initializeMappings() {
        // 配置路径模式 -> 控制器类
        routeMappings.put("/{customerId}/session", SessionController.class);
        routeMappings.put("/{betOfferId}/stake", StakeController.class);
        routeMappings.put("/{betOfferId}/highstakes", HighStakesController.class);

        // 可以轻松添加新路由：
        // routeMappings.put("/{customerId}/history", BettingHistoryController.class);

        System.out.println("Route mappings initialized:");
        routeMappings.forEach((path, controller) ->
                System.out.println("  " + path + " -> " + controller.getSimpleName())
        );
    }

    /**
     * 根据路径查找控制器类
     */
    public Class<? extends BaseController> findControllerClass(String path) {
        for (Map.Entry<String, Class<? extends BaseController>> entry : routeMappings.entrySet()) {
            if (matchesPathPattern(entry.getKey(), path)) {
                return entry.getValue();
            }
        }
        return null;
    }

    /**
     * 创建控制器实例并注入依赖
     */
    public BaseController createController(Class<? extends BaseController> controllerClass) {
        try {
            // 获取所有构造器
            var constructors = controllerClass.getConstructors();

            for (var constructor : constructors) {
                Class<?>[] paramTypes = constructor.getParameterTypes();
                Object[] parameters = new Object[paramTypes.length];
                boolean allParametersResolved = true;

                // 为每个参数类型查找依赖
                for (int i = 0; i < paramTypes.length; i++) {
                    parameters[i] = findDependency(paramTypes[i]);
                    if (parameters[i] == null) {
                        System.err.println("Dependency not found: " + paramTypes[i].getName());
                        allParametersResolved = false;
                        break;
                    }
                }

                // 如果所有依赖都找到，创建实例
                if (allParametersResolved) {
                    return (BaseController) constructor.newInstance(parameters);
                }
            }

            // 如果没有匹配的构造器，使用默认构造器
            return controllerClass.getDeclaredConstructor().newInstance();

        } catch (Exception e) {
            throw new RuntimeException("Failed to create controller: " + controllerClass.getName(), e);
        }
    }

    /**
     * 查找依赖实例 单例模式、
     */
    public Object findDependency(Class<?> dependencyType) {
        // 直接查找该类型
        Object dependency = dependencies.get(dependencyType);
        if (dependency != null) {
            return dependency;
        }

        // 如果没有直接找到，查找兼容的类型
        for (Map.Entry<Class<?>, Object> entry : dependencies.entrySet()) {
            if (dependencyType.isAssignableFrom(entry.getKey())) {
                return entry.getValue();
            }
        }

        return null;
    }

    /**
     * 从路径中提取参数
     */
    public Map<String, String> extractPathParameters(String pattern, String path) {
        Map<String, String> params = new HashMap<>();
        String[] patternParts = pattern.split("/");
        String[] pathParts = path.split("/");

        for (int i = 0; i < patternParts.length; i++) {
            if (patternParts[i].startsWith("{") && patternParts[i].endsWith("}")) {
                String paramName = patternParts[i].substring(1, patternParts[i].length() - 1);
                params.put(paramName, pathParts[i]);
            }
        }
        return params;
    }

    /**
     * 获取匹配的路由模式
     */
    public String findMatchedPattern(String path) {
        for (String pattern : routeMappings.keySet()) {
            if (matchesPathPattern(pattern, path)) {
                return pattern;
            }
        }
        return null;
    }

    /**
     * 路径模式匹配
     */
    private boolean matchesPathPattern(String pattern, String path) {
        System.out.println(pattern + path);
        String[] patternParts = pattern.split("/");
        String[] pathParts = path.split("/");

        if (patternParts.length != pathParts.length) {
            return false;
        }

        for (int i = 0; i < patternParts.length; i++) {
            if (patternParts[i].startsWith("{") && patternParts[i].endsWith("}")) {
                // 参数部分，匹配任何非空字符串
                if (pathParts[i].isEmpty()) {
                    return false;
                }
            } else if (!patternParts[i].equals(pathParts[i])) {
                // 固定部分必须精确匹配
                return false;
            }
        }
        return true;
    }

    /**
     * 关闭所有资源
     */
    public void shutdown() {
        // 关闭需要关闭的服务
        SessionService sessionService = (SessionService) dependencies.get(SessionService.class);
        if (sessionService != null) {
            sessionService.shutdown();
        }

        System.out.println("Router config shutdown completed");
    }

    /**
     * 添加新的路由映射（运行时扩展） 可以搭配参数中心使用
     */
    public void addRouteMapping(String path, Class<? extends BaseController> controllerClass) {
        routeMappings.put(path, controllerClass);
    }

    /**
     * 添加新的依赖（运行时扩展） 可以搭配参数中心使用
     */
    public <T> void addDependency(Class<T> dependencyType, T instance) {
        dependencies.put(dependencyType, instance);
    }
}